package com.ymatou.iapi.settlement.testcase;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.http.client.ClientProtocolException;
import org.json.JSONArray;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;

import com.ymatou.iapi.settlement.parameter.OrderSettlementReq;
import com.ymatou.iapi.settlement.parameter.GenerateRefundCommissionInvoiceBean;
import com.ymatou.iapi.settlement.parameter.SettleRefundCommissionBean;
import com.ymatou.iapi.settlement.parameter.SettleSellerIncomeAndChargeCommissionBean;
import com.ymatou.iapi.settlement.service.GenerateInvoicesOnOrderReceivedCall;
import com.ymatou.iapi.settlement.service.GenerateRefundCommissionInvoiceCall;
import com.ymatou.iapi.settlement.service.SettleRefundCommissionCall;
import com.ymatou.iapi.settlement.service.SettleSellerIncomeAndChargeCommissionCall;
import com.ymatou.iapi.trading.operate.parameter.ActivityVo;
import com.ymatou.iapi.trading.operate.parameter.OrderGroupVo;
import com.ymatou.iapi.trading.operate.parameter.OrderItemVo;
import com.ymatou.iapi.trading.operate.parameter.OrderVo;
import com.ymatou.iapi.trading.operate.parameter.SellerCouponVo;
import com.ymatou.iapi.trading.operate.parameter.YmatouCouponVo;
import com.ymatou.iapi.trading.operate.parameter.enums.ActivityPromotionTypeEnum;
import com.ymatou.iapi.trading.operate.parameter.enums.AppTerminalSourceEnum;
import com.ymatou.iapi.trading.operate.parameter.enums.LogisticsTypeEnum;
import com.ymatou.iapi.trading.operate.parameter.enums.OrderSourceEnum;
import com.ymatou.iapi.trading.operate.parameter.enums.OrderTypeEnum;
import com.ymatou.iapi.trading.operate.parameter.enums.PriceTypeEnum;
import com.ymatou.iapi.trading.operate.parameter.enums.ProductRefundChannelEnum;
import com.ymatou.iapi.trading.operate.parameter.enums.SalesTypeEnum;
import com.ymatou.iapi.trading.operate.parameter.enums.SellerCouponApplianceTypeEnum;
import com.ymatou.iapi.trading.operate.parameter.enums.TerminalSourceEnum;
import com.ymatou.iapi.trading.operate.parameter.enums.YmatouCouponApplianceTypeEnum;
import com.ymatou.iapi.trading.operate.parameter.req.ApplySalesRefundRequestBean;
import com.ymatou.iapi.trading.operate.parameter.req.PlaceOrderReq;
import com.ymatou.iapi.trading.operate.service.ApplySalesRefundRequestCall;
import com.ymatou.iapi.trading.operate.service.PlaceOrderCall;
import com.ymt.base.YmatouEasyCall;
import com.ymt.core.tool.Logger;
import com.ymt.utils.annotation.TestCase;
import com.ymt.utils.annotation.TestSuite;
import com.ymt.utils.tag.P1;
import com.ymttest.business.service.CouponCallService;
import com.ymttest.business.service.OrderCallService;
import com.ymttest.business.service.ProductCallService;
import com.ymttest.business.service.UserCallService;
import com.ymttest.database.model.YmtAccountEntry;
import com.ymttest.database.model.YmtCommissionDetail;
import com.ymttest.database.sqlwapper.AccountDefaultWapper;
import com.ymttest.database.sqlwapper.DefaultWapper;
import com.ymttest.database.sqlwapper.YmtCommissionDetailWapper;
import com.ymttest.database.sqlwapper.YmtRefundWapper;
import com.ymttest.utils.EnvSetup;
import com.ymttest.utils.TestDataManager;
import com.ymttest.utils.YMTDateUtil;

/**
 * 结算退佣接口 FreeMaker Template自动生成代码
 */
@TestSuite
public class Ts_SettleRefundCommission {
	private static SettleRefundCommissionBean settlerefundcommissionBean;
	private static SettleRefundCommissionCall settlerefundcommissionCall;

	private static GenerateRefundCommissionInvoiceBean generaterefundcommissioninvoiceBean;
	private static GenerateRefundCommissionInvoiceCall generaterefundcommissioninvoiceCall;

	private static OrderSettlementReq generateinvoicesonorderreceivedBean;
	private static GenerateInvoicesOnOrderReceivedCall generateinvoicesonorderreceivedCall;

	private static SettleSellerIncomeAndChargeCommissionBean settlesellerincomeandchargecommissionBean;
	private static SettleSellerIncomeAndChargeCommissionCall settlesellerincomeandchargecommissionCall;

	@BeforeClass
	public static void setUp() {
		Logger.createResultFile("结算退佣接口");
	}

	@Before
	public void caseUp() {
		settlerefundcommissionBean = new SettleRefundCommissionBean();
		settlerefundcommissionCall = new SettleRefundCommissionCall();

		generaterefundcommissioninvoiceBean = new GenerateRefundCommissionInvoiceBean();
		generaterefundcommissioninvoiceCall = new GenerateRefundCommissionInvoiceCall();

		generateinvoicesonorderreceivedBean = new OrderSettlementReq();
		generateinvoicesonorderreceivedCall = new GenerateInvoicesOnOrderReceivedCall();

		settlesellerincomeandchargecommissionBean = new SettleSellerIncomeAndChargeCommissionBean();
		settlesellerincomeandchargecommissionCall = new SettleSellerIncomeAndChargeCommissionCall();
	}

	@AfterClass
	public static void tearDown() {
		Logger.generateResult(settlerefundcommissionCall.getOpurl());
	}

	@After
	public void caseDown() {
		Logger.end();
	}

	/**
	 * 计算期望的单件商品实际支付金额
	 * 
	 * @param orderInfoId
	 * @return
	 */
	private BigDecimal calcCommissionPerProd(String orderInfoId) {
		BigDecimal payAmount = BigDecimal.ZERO;
		DefaultWapper defaultWapper = new DefaultWapper();

		List<Map> ymtOrderInfoList = defaultWapper
				.selectOrderInfoByOrderInfoId(orderInfoId);

		BigDecimal fProductPrice = (BigDecimal) ymtOrderInfoList.get(0).get(
				"fProductPrice");
		int iAmount = (Integer) ymtOrderInfoList.get(0).get("iAmount");
		BigDecimal fDiscount = (BigDecimal) ymtOrderInfoList.get(0).get(
				"fDiscount");
		BigDecimal fFreight = (BigDecimal) ymtOrderInfoList.get(0).get(
				"fFreight");
		BigDecimal fSellerPromotionAmount = (BigDecimal) ymtOrderInfoList
				.get(0).get("fSellerPromotionAmount");
		BigDecimal fSellerCouponAmount = (BigDecimal) ymtOrderInfoList.get(0)
				.get("fSellerCouponAmount");
		BigDecimal fYmtCouponAmount = (BigDecimal) ymtOrderInfoList.get(0).get(
				"fYmtCouponAmount");

		payAmount = fProductPrice.multiply(new BigDecimal(iAmount))
				.add(fDiscount).add(fFreight).subtract(fSellerPromotionAmount)
				.subtract(fSellerCouponAmount).subtract(fYmtCouponAmount);
		return payAmount.divide(new BigDecimal(iAmount), 2,
				BigDecimal.ROUND_HALF_UP);
	}

	/**
	 * 商品部分退款
	 * 
	 * @param orderId
	 * @param money 部分退款金额
	 * @param orderCallService
	 * @return refundBillNo
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	private String partRefund(int orderId, int money,
			OrderCallService orderCallService) throws ClientProtocolException,
			IOException {
		// 申请部分退款
		ApplySalesRefundRequestBean applysalesrefundrequestBean = orderCallService
				.applySalesRefundRequestInJavaBean(orderId);
		String refundBillNo = applysalesrefundrequestBean
				.getSalesRefundInfoList().get(0).getRefundBillNo();
		String CatalogId = applysalesrefundrequestBean.getSalesRefundInfoList()
				.get(0).getCatalogId();
		String OrderInfoId = (String) new DefaultWapper()
				.selectOrderInfoByOderId(orderId).stream()
				.filter(a -> a.get("sCatalogId").equals(CatalogId))
				.collect(Collectors.toList()).get(0).get("sOrderInfoId");
		BigDecimal CommissionPerProd = calcCommissionPerProd(OrderInfoId);
		applysalesrefundrequestBean.getSalesRefundInfoList().get(0)
				.setRefundAmount(CommissionPerProd.add(new BigDecimal(money)));
		ApplySalesRefundRequestCall applysalesrefundrequestCall = new ApplySalesRefundRequestCall();
		applysalesrefundrequestCall.setData(false, applysalesrefundrequestBean);
		applysalesrefundrequestCall.callService();

		// 退款处理
		orderCallService.salesrefundsuccessrequest(applysalesrefundrequestBean);
		return refundBillNo;
	}

	// 一个订单下面多个商品
	private Map placeOrder() {
		Map map = new HashMap();
		try {
			PlaceOrderReq placeorderBean = new PlaceOrderReq();
			PlaceOrderCall placeorderCall = new PlaceOrderCall();
			// int userId = Integer.valueOf(EnvSetup.getData("BuyUserId"));
			// 注册新用户
			Map newUser = new HashMap();
			newUser = new UserCallService().registerByMobile();
			int userId = (Integer) newUser.get("userid");
			int sellerId = Integer.valueOf(EnvSetup.getData("SellerId"));
			// 创建产品
			Logger.comment("前置数据准备");
			HashMap<String, Object> productInfo = ProductCallService
					.createProduct(sellerId, 3);
			Logger.comment("前置数据准备结束");
			String productId = (String) productInfo.get("productId");
			Logger.debug("productId:" + productId);
			String productName = (String) productInfo.get("productName");
			String pic = (String) productInfo.get("pic");
			BigDecimal price = (BigDecimal) (productInfo.get("price"));
			String catalogId = (String) productInfo.get("catalogId");
			YmatouCouponVo ymtCoupon = new YmatouCouponVo();
			// 平台优惠券
			BigDecimal couponValue = new BigDecimal(13);
			String couponCode = new OrderCallService().receivePlatformCoupon(
					userId, couponValue);
			ymtCoupon.setApplianceType(YmatouCouponApplianceTypeEnum.ALL);
			ymtCoupon.setCouponCode(couponCode);
			ymtCoupon.setCouponValue(couponValue);
			placeorderBean.setAppId("AutoTest");
			placeorderBean.setYmatouCoupon(ymtCoupon);
			placeorderBean.setUserId(userId);
			placeorderBean.setRequestId(TestDataManager.getRandomUUID()
					.toString());
			placeorderBean.setTerminalSource(TerminalSourceEnum.IOS);
			placeorderBean.setAppTerminalSource(AppTerminalSourceEnum.Phone);
			placeorderBean.setSourceIp("127.0.0.1");
			placeorderBean.setAppId("ios");
			placeorderBean.setDeviceId("7777777777888888888888999");
			OrderGroupVo groupVo1 = new OrderGroupVo();
			placeorderBean.setOrderSource(OrderSourceEnum.PC);
			// 商家优惠券
			BigDecimal sellerCouponValue = new BigDecimal(15);
			String sellerCouponCode = new CouponCallService()
					.receiveCouponInfo(sellerId, userId, couponValue);
			SellerCouponVo sellerCoupon = new SellerCouponVo();
			sellerCoupon.setApplianceType(SellerCouponApplianceTypeEnum.ALL);
			sellerCoupon.setCouponCode(sellerCouponCode);
			sellerCoupon.setCouponValue(sellerCouponValue);
			groupVo1.setSellerCoupon(sellerCoupon);
			groupVo1.setSellerId(sellerId);
			List<OrderVo> orders = new ArrayList<OrderVo>();
			OrderVo ordervo1 = new OrderVo();
			ordervo1.setAutoCancelOrderHours(new BigDecimal(1));
			ordervo1.setOrderType(OrderTypeEnum.Spot);
			ordervo1.setPaidFull(true);
			ordervo1.setAddress("上海市闸北区灵石路636号");
			ordervo1.setLeaveWord("ymt autotest");
			ordervo1.setPhone("13100000001");
			ordervo1.setPostCode("200001");
			ordervo1.setTelephone("021-51002100");
			ordervo1.setReceiveName("李四");
			List<OrderItemVo> items = new ArrayList<OrderItemVo>();
			OrderItemVo orderitem1 = new OrderItemVo();
			orderitem1.setCatalogId(TestDataManager.getRandomUUID().toString());
			orderitem1.setProductNum(3);
			orderitem1.setProductName(productName);
			orderitem1.setPriceType(PriceTypeEnum.VipPrice);
			orderitem1.setProductId(TestDataManager.getRandomUUID().toString());
			price = new BigDecimal(210);
			orderitem1.setEarnestPrice(price);
			orderitem1.setProductPrice(price);
			orderitem1.setOriginalPrice(price);
			orderitem1.setSalesType(SalesTypeEnum.AlreadyInStock);
			orderitem1.setLogisticsType(LogisticsTypeEnum.SailProtect);
			orderitem1
					.setProductRefundChannel(ProductRefundChannelEnum.Official);
			orderitem1.setBrandId(5);
			orderitem1.setPackageNo("11111111");
			orderitem1.setFirstCategoryId(111111111);
			orderitem1.setSecondCategoryId(22222222);
			orderitem1.setSecondCategoryId(33333);
			orderitem1
					.setProductDetailInfo("e5a1eccf-6a14-458f-b907-35dc9a3d2713#适用人群:b13e9eb1-98d6-4d39-8c35-225758e443d3#男");
			orderitem1.setProductRecordNo("1234567");
			orderitem1
					.setProductRefundChannel(ProductRefundChannelEnum.Official);
			orderitem1
					.setProperty("06f25e0c-e431-44ae-8a07-4d0bc824e3bd#尺寸:951a814e-2ded-4241-b9a0-91b2cd9a44fd#6,d2f663ea-3214-4344-abce-a8eaffcc43ce#颜色:f3ed3ad7-a084-450b-b698-256542963306#红色");
			ActivityVo activity = new ActivityVo();
			activity.setActivityId(46870);
			activity.setActivityBeginDate(YMTDateUtil.getBeforeOrNextDay(-10,
					"yyyy-MM-dd'T'HH:mm:ss"));
			activity.setActivityEndDate(YMTDateUtil.getBeforeOrNextDay(10,
					"yyyy-MM-dd'T'HH:mm:ss"));
			activity.setActivityTemplateId(12345678);
			activity.setCommissionRate(new BigDecimal(1.1));
			activity.setCost(true);
			activity.setFeeFree(false);
			activity.setPremium(new BigDecimal(1.5));
			activity.setPromotionPrice(new BigDecimal(15));
			activity.setPromotionType(ActivityPromotionTypeEnum.DiscountRate);
			activity.setUseCoupon(true);
			orderitem1.setActivity(activity);
			ordervo1.setOrderItems(items);
			ordervo1.setFreight(new BigDecimal("21"));
			// 第2件商品
			OrderItemVo orderitem2 = new OrderItemVo();
			orderitem2.setCatalogId("edbcc2c9-1ba9-4b04-ab88-940f63271823");
			orderitem2.setProductNum(1);
			orderitem2.setProductName(productName);
			orderitem2.setPriceType(PriceTypeEnum.VipPrice);
			orderitem2.setProductId(TestDataManager.getRandomUUID().toString());
			price = new BigDecimal(270);
			orderitem2.setEarnestPrice(price);
			orderitem2.setProductPrice(price);
			orderitem2.setOriginalPrice(price);
			orderitem2.setSalesType(SalesTypeEnum.AlreadyInStock);
			orderitem2.setLogisticsType(LogisticsTypeEnum.SailProtect);
			orderitem2
					.setProductRefundChannel(ProductRefundChannelEnum.Official);
			orderitem2.setBrandId(5);
			orderitem2.setPackageNo("11111111");
			orderitem2.setFirstCategoryId(111111111);
			orderitem2.setSecondCategoryId(22222222);
			orderitem2.setSecondCategoryId(33333);
			orderitem2
					.setProductDetailInfo("e5a1eccf-6a14-458f-b907-35dc9a3d2713#适用人群:b13e9eb1-98d6-4d39-8c35-225758e443d3#男");
			orderitem2.setProductRecordNo("1234567");
			orderitem2
					.setProductRefundChannel(ProductRefundChannelEnum.Official);
			orderitem2
					.setProperty("06f25e0c-e431-44ae-8a07-4d0bc824e3bd#尺寸:951a814e-2ded-4241-b9a0-91b2cd9a44fd#6,d2f663ea-3214-4344-abce-a8eaffcc43ce#颜色:f3ed3ad7-a084-450b-b698-256542963306#红色");
			orderitem2.setActivity(activity);
			items.add(orderitem1);
			items.add(orderitem2);
			ordervo1.setOrderItems(items);
			ordervo1.setFreight(new BigDecimal("21"));
			orders.add(ordervo1);
			groupVo1.setOrders(orders);
			placeorderBean.setOrderGroups(Arrays.asList(groupVo1));
			placeorderCall.setData(false, placeorderBean);
			placeorderCall.callService();
			JSONArray orderIds = placeorderCall.getOrderIds();
			int tradingId = placeorderCall.getTradingId();
			map.put("orderIds", orderIds);
			map.put("tradingId", tradingId);
		} catch (Exception e) {
			Logger.fail(e);
		}
		return map;
	}

	@SuppressWarnings("rawtypes")
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SettleRefundCommission_001() {
		Logger.start(true, "结算退佣成功, 单个商品全额退款");
		try {
			Map map = placeOrder();
			int userId = Integer.valueOf(EnvSetup.getData("BuyUserId"));
			int sellerId = Integer.valueOf(EnvSetup.getData("SellerId"));
			JSONArray orderIds = (JSONArray) map.get("orderIds");
			int tradingId = (Integer) map.get("tradingId");
			int orderId = orderIds.getInt(0);
			OrderCallService orderCallService = new OrderCallService();
			// 应付款全金额
			BigDecimal totalPrice = orderCallService
					.getNeedPrePayAmountOfCash(orderId);
			// 支付订单
			orderCallService.orderPayRequest(userId, totalPrice, tradingId);

			YmatouEasyCall payPayMqSenderCall = new YmatouEasyCall("", "POST",
					"JSON");
			String payPayMqSenderString = "{\"orderId\":" + orderId + "}";
			payPayMqSenderCall
					.setUrl("http://operate.trading.iapi.ymatou.com/api/trading/onOrderPaid");
			payPayMqSenderCall.setData(payPayMqSenderString);
			Logger.comment("支付发送消息");
			payPayMqSenderCall.callService();
			// 接单
			orderCallService.acceptOrder(orderId, sellerId);
			// 商家发货
			orderCallService.dispatched(orderId, sellerId);
			// 确认收货
			orderCallService.confirmReceive(userId, orderId);
			// 确认收货时生成结算单
			generateinvoicesonorderreceivedBean.setOrderId(orderId);
			generateinvoicesonorderreceivedCall
					.setData(generateinvoicesonorderreceivedBean);
			generateinvoicesonorderreceivedCall.callService();
			// 结算收入和扣佣
			settlesellerincomeandchargecommissionBean.setOrderId(orderId);
			settlesellerincomeandchargecommissionCall
					.setData(settlesellerincomeandchargecommissionBean);
			settlesellerincomeandchargecommissionCall.callService();

			Thread.sleep(2000);

			// 第一个商品全款退款
			ApplySalesRefundRequestBean applysalesrefundrequestBean = orderCallService
					.applySalesRefundRequestInJava(orderId);

			// 退款执行
			orderCallService
					.salesrefundsuccessrequest(applysalesrefundrequestBean);

			// 退款成功消息是异步操作，所以需要等待一段时间
			Thread.sleep(2000l);
			generaterefundcommissioninvoiceBean.setOrderId(orderId);
			GenerateRefundCommissionInvoiceBean.ParamExt paramExt = new GenerateRefundCommissionInvoiceBean.ParamExt();
			String refundBillNo = applysalesrefundrequestBean
					.getSalesRefundInfoList().get(0).getRefundBillNo();
			paramExt.setRefundBillNo(refundBillNo);
			generaterefundcommissioninvoiceBean.setParamExt(paramExt);
			// 生成确认收货后的退货退款所引起的退佣结算单
			generaterefundcommissioninvoiceCall
					.setData(generaterefundcommissioninvoiceBean);
			generaterefundcommissioninvoiceCall.callService();
			Logger.verifyEquals("ok",
					generaterefundcommissioninvoiceCall.getReturnData(),
					"验证返回结果");

			Map m = new HashMap();
			m.put("orderId", orderId);
			m.put("refundBillNo", refundBillNo);
			List<Map> refunds = new YmtRefundWapper().selectRefundInfo(m);
			String OrderInfoId = (String) refunds.get(0).get("OrderInfoId");
			BigDecimal RefundedAmountOfCash = (BigDecimal) refunds.get(0).get(
					"RefundedAmountOfCash"); // 退货退款单退回金额
			int RefundProductNum = (int) refunds.get(0).get("RefundProductNum"); // 可退佣金商品数量

			List<YmtCommissionDetail> details = new YmtCommissionDetailWapper()
					.selectByOrderId(orderId);
			List<YmtCommissionDetail> x = details.stream()
					.filter(a -> a.getOrderInfoId().equals(OrderInfoId))
					.collect(Collectors.toList());
			YmtCommissionDetail refundCommition = x.stream()
					.filter(a -> a.getInvoiceType() == 5)
					.collect(Collectors.toList()).get(0);
			YmtCommissionDetail billConmtion = x.stream()
					.filter(a -> a.getInvoiceType() == 4)
					.collect(Collectors.toList()).get(0);

			BigDecimal RealPayAmountPerProd = refundCommition
					.getRealPayAmountPerProd(); // 单件商品实际支付金额
			BigDecimal CommissionPerProd = refundCommition
					.getCommissionPerProd(); // 单件商品实际收佣金额
			BigDecimal SingleCommissionRate = refundCommition
					.getSingleCommissionRate(); // 退佣比例

			Logger.verifyEquals(billConmtion.getCommissionPerProd(),
					refundCommition.getCommissionPerProd(),
					"验证退佣的单个商品佣金CommissionPerProd");
			// 可退佣金商品数量=min[int（退货退款单退回金额/单件商品实际支付金额），退回数量]
			int expProdNumOfCommission = Integer.min(RefundedAmountOfCash
					.divide(RealPayAmountPerProd, BigDecimal.ROUND_DOWN)
					.intValue(), RefundProductNum);
			Logger.verifyEquals(expProdNumOfCommission,
					refundCommition.getProdNumOfCommission(),
					"验证Ymt_CommissionDetail表可退佣金商品数量");
			// 退回商品佣金= [单件商品实际收佣金额－单件商品已返佣金]×可退佣金商品数量×退佣比例
			BigDecimal expCommissionAmount = CommissionPerProd
					.multiply(new BigDecimal(expProdNumOfCommission))
					.multiply(SingleCommissionRate)
					.divide(new BigDecimal(1), 2, BigDecimal.ROUND_HALF_UP);
			Logger.verifyEquals(expCommissionAmount,
					refundCommition.getCommissionAmount(),
					"验证Ymt_CommissionDetail表的退佣金额");
			// 结算退佣前取用户账户表的余额
			Map accountInfoBeforeRefundCommition = new AccountDefaultWapper()
					.selectAccountInfoByUserId(sellerId, 1).get(0);
			BigDecimal fAvailAmountBeforeRefundCommition = (BigDecimal) accountInfoBeforeRefundCommition
					.get("fAvailAmount");
			Logger.comment("前置数据准备结束");

			settlerefundcommissionBean.setOrderId(orderId);
			settlerefundcommissionBean.setRefundBillNo(refundBillNo);
			settlerefundcommissionCall.setData(settlerefundcommissionBean);
			// 结算退佣
			settlerefundcommissionCall.callService();
			Logger.verifyEquals("ok",
					settlerefundcommissionCall.getReturnData(),
					"验证SettlerefundcommissionCall返回结果");
			Map m1 = new HashMap();
			m1.put("bizno", refundBillNo);
			YmtAccountEntry entry = new AccountDefaultWapper()
					.selectAccountEntryByBizNo(m1).get(0);
			Logger.verifyEquals(expCommissionAmount, entry.getAmount(),
					"验证支付流水表退佣金额");
			BigDecimal expAvailAmount = fAvailAmountBeforeRefundCommition
					.add(expCommissionAmount);
			// 结算退佣后取用户账户表的余额
			Map accountInfoAfterRefundCommition = new AccountDefaultWapper()
					.selectAccountInfoByUserId(sellerId, 1).get(0);
			BigDecimal fAvailAmountAfterRefundCommition = (BigDecimal) accountInfoAfterRefundCommition
					.get("fAvailAmount");
			Logger.verifyEquals(expAvailAmount,
					fAvailAmountAfterRefundCommition,
					"检查退佣结算成功后ymt_AccountInfo的用户余额");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@SuppressWarnings("rawtypes")
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SettleRefundCommission_002() {
		Logger.start(true, "结算退佣成功, 单个商品部分退款");
		try {
			Map map = placeOrder();
			int userId = Integer.valueOf(EnvSetup.getData("BuyUserId"));
			int sellerId = Integer.valueOf(EnvSetup.getData("SellerId"));
			JSONArray orderIds = (JSONArray) map.get("orderIds");
			int tradingId = (Integer) map.get("tradingId");
			int orderId = orderIds.getInt(0);
			OrderCallService orderCallService = new OrderCallService();
			// 应付款全金额
			BigDecimal totalPrice = orderCallService
					.getNeedPrePayAmountOfCash(orderId);
			// 支付订单
			orderCallService.orderPayRequest(userId, totalPrice, tradingId);

			YmatouEasyCall payPayMqSenderCall = new YmatouEasyCall("", "POST",
					"JSON");
			String payPayMqSenderString = "{\"orderId\":" + orderId + "}";
			payPayMqSenderCall
					.setUrl("http://operate.trading.iapi.ymatou.com/api/trading/onOrderPaid");
			payPayMqSenderCall.setData(payPayMqSenderString);
			Logger.comment("支付发送消息");
			payPayMqSenderCall.callService();
			// 接单
			orderCallService.acceptOrder(orderId, sellerId);
			// 商家发货
			orderCallService.dispatched(orderId, sellerId);
			// 确认收货
			orderCallService.confirmReceive(userId, orderId);
			// 确认收货时生成结算单
			generateinvoicesonorderreceivedBean.setOrderId(orderId);
			generateinvoicesonorderreceivedCall
					.setData(generateinvoicesonorderreceivedBean);
			generateinvoicesonorderreceivedCall.callService();
			// 结算收入和扣佣
			settlesellerincomeandchargecommissionBean.setOrderId(orderId);
			settlesellerincomeandchargecommissionCall
					.setData(settlesellerincomeandchargecommissionBean);
			settlesellerincomeandchargecommissionCall.callService();
			// 第一个商品部分退款
			String refundBillNo = partRefund(orderId, -1, orderCallService);
			// 生成确认收货后的退货退款所引起的退佣结算单前记录账户余额
			Map accountInfoBeforeRefundCommition = new AccountDefaultWapper()
					.selectAccountInfoByUserId(sellerId, 1).get(0);
			BigDecimal fAvailAmountBeforeRefundCommition = (BigDecimal) accountInfoBeforeRefundCommition
					.get("fAvailAmount");

			// 退款成功消息是异步操作，所以需要等待一段时间
			Thread.sleep(2000l);
			generaterefundcommissioninvoiceBean.setOrderId(orderId);
			GenerateRefundCommissionInvoiceBean.ParamExt paramExt = new GenerateRefundCommissionInvoiceBean.ParamExt();
			paramExt.setRefundBillNo(refundBillNo);
			generaterefundcommissioninvoiceBean.setParamExt(paramExt);
			generaterefundcommissioninvoiceCall
					.setData(generaterefundcommissioninvoiceBean);
			generaterefundcommissioninvoiceCall.callService();
			Logger.verifyEquals("ok",
					generaterefundcommissioninvoiceCall.getReturnData(),
					"验证返回结果");
			// 生成确认收货后的退货退款所引起的退佣结算单后记录账户余额
			Map accountInfoAfterRefundCommition = new AccountDefaultWapper()
					.selectAccountInfoByUserId(sellerId, 1).get(0);
			BigDecimal fAvailAmountAfterRefundCommition = (BigDecimal) accountInfoAfterRefundCommition
					.get("fAvailAmount");
			Logger.verifyEquals(fAvailAmountBeforeRefundCommition,
					fAvailAmountAfterRefundCommition, "验证未发生退佣结算前，余额不变");

			Map m = new HashMap();
			m.put("orderId", orderId);
			m.put("refundBillNo", refundBillNo);
			List<Map> refunds = new YmtRefundWapper().selectRefundInfo(m);
			String OrderInfoId = (String) refunds.get(0).get("OrderInfoId");

			List<YmtCommissionDetail> details = new YmtCommissionDetailWapper()
					.selectByOrderId(orderId);
			List<YmtCommissionDetail> x = details.stream()
					.filter(a -> a.getOrderInfoId().equals(OrderInfoId))
					.collect(Collectors.toList());
			YmtCommissionDetail refundCommition = x.stream()
					.filter(a -> a.getInvoiceType() == 5)
					.collect(Collectors.toList()).get(0);
			YmtCommissionDetail billConmtion = x.stream()
					.filter(a -> a.getInvoiceType() == 4)
					.collect(Collectors.toList()).get(0);

			Logger.verifyEquals(billConmtion.getCommissionPerProd(),
					refundCommition.getCommissionPerProd(),
					"验证退佣的单个商品佣金CommissionPerProd");
			// 部分退款，可退商品数量设置为0
			Logger.verifyEquals(0, refundCommition.getProdNumOfCommission(),
					"验证Ymt_CommissionDetail表可退佣金商品数量");
			// 部分退款，可退佣金金额为0.00
			Logger.verifyEquals(new BigDecimal(0.00).divide(new BigDecimal(1),
					2, BigDecimal.ROUND_HALF_UP), refundCommition
					.getCommissionAmount(), "验证Ymt_CommissionDetail表的退佣金额");
			Logger.comment("前置数据准备结束");

			settlerefundcommissionBean.setOrderId(orderId);
			settlerefundcommissionBean.setRefundBillNo(refundBillNo);
			settlerefundcommissionCall.setData(settlerefundcommissionBean);
			// 结算退佣
			settlerefundcommissionCall.callService();
			Logger.verifyEquals("ok",
					settlerefundcommissionCall.getReturnData(),
					"验证SettlerefundcommissionCall返回结果");
			Map m1 = new HashMap();
			m1.put("bizno", refundBillNo);
			List<YmtAccountEntry> entrys = new AccountDefaultWapper()
					.selectAccountEntryByBizNo(m1);
			Logger.verifyEquals(0, entrys.size(), "验证资金流水表中没有退佣的记录");
			// BigDecimal expAvailAmount =
			// fAvailAmountBeforeRefundCommition.add(expCommissionAmount);
			// //结算退佣后取用户账户表的余额
			// Map accountInfoAfterRefundCommition = new
			// AccountDefaultWapper().selectAccountInfoByUserId(sellerId, 1).get(0);
			// BigDecimal fAvailAmountAfterRefundCommition =
			// (BigDecimal)accountInfoAfterRefundCommition.get("fAvailAmount");
			// Logger.verifyEquals(expAvailAmount, fAvailAmountAfterRefundCommition,
			// "检查退佣结算成功后ymt_AccountInfo的用户余额");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
}
